﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;
using System.IO;
using System.Globalization;

namespace CarBloke
{
    public class LogEntry
    {
        public enum LogTypes
        {
            Fuel,
            Oil,
            Other
        }

        public Guid ID { get; set; }
        public Guid VehicleID { get; set; }        
        public DateTime LogTime { get; set; }
        public LogTypes LogType { get; set; }
        public Double OdometerReading { get; set; }
        public Double Cost { get; set; }
        public Double FuelAdded { get; set; }
        public Boolean FullTank { get; set; }
        public Boolean MissedLogs { get; set; }
        public String Description { get; set; }
        public String Notes { get; set; }


        //UI Labels for binding
        public String FuelAddedLabel
        {
            get
            {
                Double fuelVolume = UnitConversions.Convert(this.FuelAdded, ApplicationSettings.VolumeUnits.Liter, ApplicationSettings.Current.VolumeUnit);
                return fuelVolume.ToString("f3", CultureInfo.CurrentCulture) + " " + ApplicationSettings.ToLongString(ApplicationSettings.Current.VolumeUnit, fuelVolume != 1);
            }
        }

        public String MileageLabel
        {
            get
            {
                LogEntry priorLog = App.LoadPriorLogEntry(this.VehicleID, this.ID, this.LogType);
                if (priorLog != null)
                {
                    Double fuelEfficiencyKmL = VehicleMath.CalculateFuelEfficiency(priorLog, this);
                    if (!Double.IsNaN(fuelEfficiencyKmL))
                    {
                        Double fuelEfficiency = UnitConversions.Efficiency(fuelEfficiencyKmL, ApplicationSettings.Current.EfficiencyUnit);
                        return fuelEfficiency.ToString("f") + " " + ApplicationSettings.ToString(ApplicationSettings.Current.EfficiencyUnit);
                    }
                }

                return "";
            }
        }

        public String OdometerLabel
        {
            get
            {
                Double distance = UnitConversions.Convert(this.OdometerReading, ApplicationSettings.DistanceUnits.Kilometers , ApplicationSettings.Current.DistanceUnit);
                int distanceRounded = (int)Math.Round(distance);
                return distanceRounded.ToString() + " " + ApplicationSettings.ToShortString(ApplicationSettings.Current.DistanceUnit);
            }
        }

        public String CostLabel
        {
            get
            {
                if (!Double.IsNaN(this.Cost))
                {
                    return this.Cost.ToString("c", CultureInfo.CurrentCulture);
                }

                return String.Empty;                   
            }
        }

        public String CostPerUnitLabel
        {
            get
            {
                if (!Double.IsNaN(this.Cost) && !Double.IsNaN(FuelAdded))
                {
                    double currentUnitQuantity = UnitConversions.Convert(this.FuelAdded, ApplicationSettings.VolumeUnits.Liter, ApplicationSettings.Current.VolumeUnit);
                    double costPerUnit = this.Cost / currentUnitQuantity;

                    return costPerUnit.ToString("c3", CultureInfo.CurrentCulture) + "/" + ApplicationSettings.ToShortString(ApplicationSettings.Current.VolumeUnit);
                }

                return String.Empty;
            }
        }

        public String LogTimeLabel
        {
            get
            {
                return this.LogTime.ToString("d");
            }
        }

        public String NotesLabel
        {
            get
            {
                return this.Notes;
            }
        }

        public String TimeSinceOilChangeLabel
        {
            get
            {
                LogEntry priorLog = App.LoadPriorLogEntry(this.VehicleID, this.ID, this.LogType);
                if (priorLog != null && this.LogTime > priorLog.LogTime)
                {
                    DateDifference dateDifference = new DateDifference(this.LogTime, priorLog.LogTime);
                    int TotalMonths = dateDifference.Months + 12 * dateDifference.Years;

                    //31 isn't exact, but who cares
                    double partialMonths = TotalMonths + dateDifference.Days / 31d;
                    return partialMonths.ToString("f") + " " +LanguageResources.Resources._months;
                }

                return String.Empty;
            }
        }

        public String DistanceSinceOilChangeLabel
        {
            get
            {
                LogEntry priorLog = App.LoadPriorLogEntry(this.VehicleID, this.ID, this.LogType);
                if (priorLog != null)
                {
                    double distanceDifferenceKm = this.OdometerReading - priorLog.OdometerReading;
                    double distanceDifferenceCurrentUnits = UnitConversions.Convert(distanceDifferenceKm, ApplicationSettings.DistanceUnits.Kilometers, ApplicationSettings.Current.DistanceUnit);
                    int distanceDifference = (int)Math.Round(distanceDifferenceCurrentUnits);

                    return distanceDifference.ToString() +" " + ApplicationSettings.ToShortString(ApplicationSettings.Current.DistanceUnit);
                }

                return String.Empty;
            }
        }

        public String DescriptionLabel
        {
            get
            {
                return this.Description;
            }
        }

        //UI binding by type

        public String Row0Column0
        {
            get
            {
                switch (this.LogType)
                {
                    case LogTypes.Fuel:
                        return this.FuelAddedLabel;
                    case LogTypes.Oil:
                        return this.DistanceSinceOilChangeLabel;
                    case LogTypes.Other:
                        return this.DescriptionLabel;                
                }

                return String.Empty;
            }
        }

        public String Row0Column1
        {
            get
            {
                switch (this.LogType)
                {
                    case LogTypes.Fuel:
                        return this.MileageLabel;
                    case LogTypes.Oil:
                        return this.TimeSinceOilChangeLabel;
                    case LogTypes.Other:
                        return String.Empty;
                }

                return String.Empty;
            }
        }

        public String Row0Column2
        {
            get
            {
                switch (this.LogType)
                {
                    case LogTypes.Fuel:
                        return this.CostPerUnitLabel;
                    case LogTypes.Oil:
                        return String.Empty;
                    case LogTypes.Other:
                        return String.Empty;
                }

                return String.Empty;
            }
        }

        public String Row1Column0
        {
            get
            {
                return this.LogTimeLabel;
            }
        }

        public String Row1Column1
        {
            get
            {
                return this.OdometerLabel;
            }
        }

        public String Row1Column2
        {
            get
            {
                return this.CostLabel;
            }
        }

        public String Row2Column0
        {
            get
            {
                return this.Notes;
            }
        }
    }
}
